package com.gitee.zycra.future.job.common.bo;

import com.gitee.zycra.future.job.common.enums.JobCycleEnum;
import com.gitee.zycra.future.job.common.enums.ScheduleRatioEnum;
import com.gitee.zycra.future.job.common.model.JobRunning;
import com.gitee.zycra.future.job.common.model.JobSchedule;
import com.gitee.zycra.future.job.common.param.AddScheduleParam;
import com.gitee.zycra.jdbc.annotation.Column;
import com.gitee.zycra.jdbc.annotation.Table;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.time.LocalDateTime;

/**
 * @author zycra
 */
@Getter
@Setter
@ToString
@Accessors(chain = true)
@Table
public class JobCalculateBO {

    /**
     * 任务调度ID
     */
    @Column("id")
    private Long jobScheduleId;

    /**
     * 任务名称
     */
    @Column("job_name")
    private String jobName;

    /**
     * 调度名称
     */
    @Column("schedule_name")
    private String scheduleName;

    /**
     * 任务类名
     */
    @Column("job_class_name")
    private String jobClassName;

    /**
     * 应用名称
     */
    @Column("application_name")
    private String applicationName;

    /**
     * 执行参数
     */
    @Column("schedule_param")
    private String scheduleParam;

    /**
     * 重试次数
     */
    @Column("retry_times")
    private Integer retryTimes;

    /**
     * 任务进度
     *
     * @see com.gitee.zycra.future.job.common.enums.ScheduleRatioEnum
     */
    @Column("schedule_ratio")
    private Integer scheduleRatio;

    /**
     * 节点IP地址
     */
    @Column("node_ip")
    private String nodeIp;

    /**
     * 失败重试间隔(分钟)
     */
    @Column("job_retry_interval")
    private Integer jobRetryInterval;

    /**
     * 失败重试次数
     */
    @Column("job_retry_times")
    private Integer jobRetryTimes;

    /**
     * 执行周期
     *
     * @see com.gitee.zycra.future.job.common.enums.JobCycleEnum
     */
    @Column("job_cycle")
    private Integer jobCycle;

    /**
     * 上次调度时间
     */
    @Column("last_schedule_time")
    private LocalDateTime lastScheduleTime;

    /**
     * 下次调度时间
     */
    @Column("next_schedule_time")
    private LocalDateTime nextScheduleTime;

    /**
     * 正常下次调度时间
     */
    @Column("normal_next_time")
    private LocalDateTime normalNextTime;

    /**
     * 月
     */
    @Column("cron_month")
    private Integer cronMonth;

    /**
     * 日
     */
    @Column("cron_day")
    private Integer cronDay;

    /**
     * 时
     */
    @Column("cron_hour")
    private Integer cronHour;

    /**
     * 分
     */
    @Column("cron_minute")
    private Integer cronMinute;

    /**
     * 秒
     */
    @Column("cron_second")
    private Integer cronSecond;


    public static JobRunning convertToJobRunning(JobCalculateBO jobCalculateBO, String nodeIp) {
        if (jobCalculateBO == null) {
            return null;
        }
        JobCycleEnum jobCycle = JobCycleEnum.getByCode(jobCalculateBO.getJobCycle());
        return new JobRunning()
                .setJobScheduleId(jobCalculateBO.getJobScheduleId())
                .setJobName(jobCalculateBO.getJobName())
                .setScheduleName(jobCalculateBO.getScheduleName())
                .setJobClassName(jobCalculateBO.getJobClassName())
                .setApplicationName(jobCalculateBO.getApplicationName())
                .setScheduleParam(jobCalculateBO.getScheduleParam())
                .setScheduleTime(jobCalculateBO.getNextScheduleTime())
                .setNormalScheduleTime(jobCalculateBO.getNormalNextTime())
                .setRetryTimes(jobCalculateBO.getRetryTimes())
                .setScheduleRatio(ScheduleRatioEnum.TO_TRIGGER.getCode())
                .setNodeIp(nodeIp)
                .setTimeoutTime(jobCalculateBO.getNextScheduleTime().equals(jobCalculateBO.getNormalNextTime())
                        ? jobCalculateBO.getNormalNextTime().plusMinutes(jobCycle.getMinutes())
                        : jobCalculateBO.getNormalNextTime());

    }

    public static JobCalculateBO buildJobCalculateBO(AddScheduleParam addScheduleParam, Integer jobCycle) {
        if (addScheduleParam == null) {
            return null;
        }
        return new JobCalculateBO()
                .setJobCycle(jobCycle)
                .setCronMonth(addScheduleParam.getCronMonth())
                .setCronDay(addScheduleParam.getCronDay())
                .setCronHour(addScheduleParam.getCronHour())
                .setCronMinute(addScheduleParam.getCronMinute())
                .setCronSecond(addScheduleParam.getCronSecond());
    }

    public static JobCalculateBO buildJobCalculateBO(JobSchedule jobSchedule, Integer jobCycle) {
        if (jobSchedule == null) {
            return null;
        }
        return new JobCalculateBO()
                .setJobCycle(jobCycle)
                .setCronMonth(jobSchedule.getCronMonth())
                .setCronDay(jobSchedule.getCronDay())
                .setCronHour(jobSchedule.getCronHour())
                .setCronMinute(jobSchedule.getCronMinute())
                .setCronSecond(jobSchedule.getCronSecond());
    }
}
